Tegra: allow platforms to override plat_core_pos_by_mpidr()
authorVarun Wadekar <[email protected]>
Tue, 31 Jan 2017 22:53:37 +0000 (14:53 -0800)
committerVarun Wadekar <[email protected]>
Fri, 7 Apr 2017 16:32:35 +0000 (09:32 -0700)
This patch makes the default implementation of plat_core_pos_by_mpidr()
as weakly linked, so that platforms can override it with their own.

Tegra186, for one, does not have CPU IDs 2 and 3, so it has its own
implementation of plat_core_pos_by_mpidr().

Change-Id: I7a5319869c01ede3775386cb95af1431792f74b3
Signed-off-by: Varun Wadekar <[email protected]>
plat/nvidia/tegra/common/tegra_topology.c
plat/nvidia/tegra/soc/t186/plat_setup.c

index 0431d98a2cfdb3397d9f6f69b6e9ef02989597dc..f4c56617b945352398d2d60012f59ba3b38d9e89 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -33,6 +33,7 @@
 #include <psci.h>
 
 extern const unsigned char tegra_power_domain_tree_desc[];
+#pragma weak plat_core_pos_by_mpidr
 
 /*******************************************************************************
  * This function returns the Tegra default topology tree information.
@@ -52,23 +53,18 @@ int plat_core_pos_by_mpidr(u_register_t mpidr)
 {
        unsigned int cluster_id, cpu_id;
 
-       mpidr &= MPIDR_AFFINITY_MASK;
-
-       if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK))
-               return -1;
-
        cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
        cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
 
        if (cluster_id >= PLATFORM_CLUSTER_COUNT)
-               return -1;
+               return PSCI_E_NOT_PRESENT;
 
        /*
         * Validate cpu_id by checking whether it represents a CPU in
         * one of the two clusters present on the platform.
         */
        if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER)
-               return -1;
+               return PSCI_E_NOT_PRESENT;
 
        return (cpu_id + (cluster_id * 4));
 }
index 71087231fdfd964e9fc6967b5e3fab9918aaed52..13f867e215e0eba033a34c9a62a58b45e3f7fa75 100644 (file)
 DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, L2CTLR_EL1)
 extern uint64_t tegra_enable_l2_ecc_parity_prot;
 
+/*******************************************************************************
+ * Tegra186 CPU numbers in cluster #0
+ *******************************************************************************
+ */
+#define TEGRA186_CLUSTER0_CORE2                2
+#define TEGRA186_CLUSTER0_CORE3                3
+
 /*******************************************************************************
  * The Tegra power domain tree has a single system level power domain i.e. a
  * single root node. The first entry in the power domain descriptor specifies
@@ -256,3 +263,40 @@ plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
 
        return (plat_params_from_bl2_t *)(uintptr_t)val;
 }
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+       unsigned int cluster_id, cpu_id, pos;
+
+       cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+       cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+       /*
+        * Validate cluster_id by checking whether it represents
+        * one of the two clusters present on the platform.
+        */
+       if (cluster_id >= PLATFORM_CLUSTER_COUNT)
+               return PSCI_E_NOT_PRESENT;
+
+       /*
+        * Validate cpu_id by checking whether it represents a CPU in
+        * one of the two clusters present on the platform.
+        */
+       if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER)
+               return PSCI_E_NOT_PRESENT;
+
+       /* calculate the core position */
+       pos = cpu_id + (cluster_id << 2);
+
+       /* check for non-existent CPUs */
+       if (pos == TEGRA186_CLUSTER0_CORE2 || pos == TEGRA186_CLUSTER0_CORE3)
+               return PSCI_E_NOT_PRESENT;
+
+       return pos;
+}